 # _*_ coding:UTF-8 _*_
import numpy as np
import win32con
import ctypes
import ctypes.wintypes
import threading
import time
import os
import sys 
import subprocess
from PIL import Image
from aip import AipOcr
import shutil
import urllib
import requests
import string
sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0]+'\\Config'))
from config import global_config


'''
热键功能，独立线程控制

'''
class Hotkey(threading.Thread):                                                            #创建一个Thread.threading的扩展类  

    def run(self):  
        global EXIT                                                                        #全局变量，这个可以在不同线程间共用
        global RUN                                                                         #全局变量，这个可以在不同线程间共用
        user32 = ctypes.windll.user32                                                      #加载user32.dll

        try:
            if not user32.RegisterHotKey(None, ID1, 0, HOTKEY_RUN):
                print ("Unable to register id", ID1) 

            if not user32.RegisterHotKey(None, ID2, 0, HOTKEY_EXIT):
                print ("Unable to register id", ID2) 

            msg = ctypes.wintypes.MSG()                                                    #检测热键是否被按下，并在最后释放快捷键  

            while True:
                if user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
                    if msg.message == win32con.WM_HOTKEY:
                        if msg.wParam == ID2:
                            EXIT=True
                            return
                        elif msg.wParam == ID1:
                            RUN=True
                    user32.TranslateMessage(ctypes.byref(msg))  
                    user32.DispatchMessageA(ctypes.byref(msg))   
        finally:
            user32.UnregisterHotKey(None, ID1)                                             #释放热键
            user32.UnregisterHotKey(None, ID2)

'''
实例定义
'''
class Ans():

    '''
    主控函数
    '''
    def main(self,OCR_RECOGNITION_MESSAGE):
        im_name=os.listdir(filePath)
        self.cutPrintScreen()                                                              #图片裁剪
        f=open(filePath+'\\'+'preOcrImg.jpg','rb')
        image=f.read()                                                                     #百度Ocr api限定入参名称image
        '''
        百度云账号，config.ini配置
        '''
        APP_ID=global_config.getRaw('config', 'APP_ID')
        API_KEY=global_config.getRaw('config', 'API_KEY')
        SECRET_KEY=global_config.getRaw('config', 'SECRET_KEY')
        client = AipOcr(APP_ID, API_KEY, SECRET_KEY)                                       #百度AipOcr，获取一个实例对象，可以调用相应函数
        information=client.basicGeneral(image)                                             #Ocr函数，输出JSON格式
        num=information['words_result_num']
        for i in range(0,num):
            OCR_RECOGNITION_MESSAGE+=information['words_result'][i]['words']
            OCR_RECOGNITION_MESSAGE+=' '

        OCR_RECOGNITION_MESSAGE=OCR_RECOGNITION_MESSAGE.translate(string.punctuation)      #字符串些处理，去除非敏感字符
        DEL=['以下','哪个','是','的','什么','下列','哪种']
        for x in DEL:
            OCR_RECOGNITION_MESSAGE = OCR_RECOGNITION_MESSAGE.replace(x,' ')

        print ('OCR_RECOGNITION_MESSAGE:',OCR_RECOGNITION_MESSAGE)
        f.close()
        '''
        shutil.rmtree(filePath)                                                            #文件清理，调试模式可不清理
        '''
        return OCR_RECOGNITION_MESSAGE

    '''
    屏幕指定位置采集函数
    '''
    def cutPrintScreen(self):
        leftPixel=int(global_config.getRaw('config', 'LEFT_PIXEL'))
        topPixel=int(global_config.getRaw('config', 'TOP_PIXEL'))
        rightPixel=int(global_config.getRaw('config', 'RIGHT_PIXEL'))
        downPixel=int(global_config.getRaw('config', 'DOWN_PIXEL'))
        #print ("config.ini FOUND SCREEN_PARAM IS : leftPixel:",leftPixel,"topPixel:",topPixel,"rightPixel:",rightPixel,"downPixel:",downPixel)
        im=Image.open(filePath+'\\'+"printScreenImg.jpg")
        if len(im.split()) == 4:
            r, g, b, a = im.split()
            im=Image.merge("RGB",(r,g,b))

        '''
        测试设备（1080x2400），其他分辨率需调整相应参数
        box（左，上，右，下）像素为单位
        '''
        box=(leftPixel,topPixel,rightPixel,downPixel)
        crop_im=im.crop(box)                                                              #裁剪函数
        im.close()
        crop_im.save(filePath+'\\'+'preOcrImg.jpg')                                       #保存本地

    '''
    屏幕内容采集函数
    '''
    def getPrintScreen(self,filePath,ADBpath):
        subprocess.call(ADBpath+"shell /system/bin/screencap -p /sdcard/printScreenImg.jpg",stdout=subprocess.PIPE, shell=subprocess.PIPE)
        subprocess.call(ADBpath+"pull /sdcard/printScreenImg.jpg "+filePath+"/printScreenImg.jpg",stdout=subprocess.PIPE, shell=subprocess.PIPE)

    '''
    文件路径设置函数
    '''
    def getfilePath(self,filePath):
        filePath=filePath.strip()                                                         #去除首位空格
        filePath=filePath.rstrip("\\")                                                    #去除尾部 \ 符号
        isDirectoryExists=os.path.exists(filePath)                                        #判断路径是否存在
        if not isDirectoryExists:                                                         #判断结果（如果不存在则创建目录,创建目录操作函数）
            os.makedirs(filePath.encode('utf-8'). decode('utf-8'))                        #UTF-8解码，避免磁盘中可能会出现乱码的情况

    '''
    设备信息抓取函数
    '''
    def getDeviceInfo(self):
        print ('------------------------------------------------')
        print ('DEVICE INFO CATCH START !')
        print ()
        print ('ADB SCRIPT CATCH (get-serialno)                :')
        subprocess.call(ADBpath+' get-serialno')                                          #设备序列号
        print ('ADB SCRIPT CATCH (getprop ro.product.model)    :')
        subprocess.call(ADBpath+' shell getprop ro.product.model')                        #设备型号
        print ('ADB SCRIPT CATCH (getprop ro.build.type)       :')
        subprocess.call(ADBpath+' shell getprop ro.build.type')                           #系统版本
        print ('ADB SCRIPT CATCH (wm size)                     :')
        subprocess.call(ADBpath+' shell wm size')                                         #设备分辨率
        print ('ADB SCRIPT CATCH (cat /proc/meminfo)           :')
        subprocess.call(ADBpath+' shell cat /proc/meminfo')                               #当前内存
        print ('ADB SCRIPT CATCH (wm density)                  :')
        subprocess.call(ADBpath+' shell wm density')                                      #物理密度
        print ()
        print ('DEVICE INFO CATCH END !')
        print ('------------------------------------------------')

    '''
    信息推送Wechat函数
    '''
    def sendMessage2Wechat(self,message):
        print ("BREAK_CONDITION('",BREAK_CONDITION,"') TRIGGERED ! PRINTSC_CATCH PROCESS CALL sendMessage2Wechat(self,message) METHOD !")
        url = 'http://sct.ftqq.com/{}.send'.format(global_config.getRaw('messenger', 'sckey'))
        payload = {
            "text":global_config.getRaw('config', 'TIPS'),
            "desp": message
        }
        headers = {
            'User-Agent':global_config.getRaw('config', 'DEFAULT_USER_AGENT')
        }
        requests.get(url, params=payload, headers=headers)

    '''
    决策交易中断条件函数
    '''
    def judgeProcessBreakCondition(self,message,breakCondition):
        if message.find(breakCondition)>=0:
            return True
        else:
            return False

    '''
    设备页面整幅刷新函数
    '''
    def swipeDevice(self):
        start_x=int(global_config.getRaw('config', 'START_X'))
        start_y=int(global_config.getRaw('config', 'START_Y'))
        end_x=int(global_config.getRaw('config', 'END_X'))
        end_y=int(global_config.getRaw('config', 'END_Y'))
        duration_ms=int(global_config.getRaw('config', 'DURATION_MS'))
        subprocess.call(ADBpath+" shell input swipe {} {} {} {} {}".format(start_x, start_y, end_x, end_y, duration_ms))
        time.sleep(int(global_config.getRaw('config', 'THREAD_SLEEP_TIME')))

if __name__ == '__main__':
        HOTKEY_RUN=0x0D                                                                    #屏幕捕捉：Enter
        HOTKEY_EXIT=win32con.VK_F8                                                         #结束程序：F8
        EXIT = False                                                                       #传递退出参数
        RUN = True                                                                         #传递启动参数（True则无需热键）
        ID1=106                                                                            #注册热键的唯一id，用来区分热键
        ID2=105
        LOOP_COUNT=0
        BREAK_CONDITION=global_config.getRaw('config', 'BREAK_CONDITION')

        printScreenCatch=os.path.split(os.path.realpath(__file__))[0]
        filePath=os.path.split(os.path.realpath(__file__))[0]+"\\PrintScreenCatchImg"
        ADBpath=printScreenCatch+'\\'+'ApkInstaller\\adb '
        ans=Ans()                                                                          #创建实例
        '''
        热键检测【目前配置（自动捕捉），无需热键检测】
        hotkey = Hotkey()
        hotkey.start()
        '''
        print ('ANDROID DEVICE USB DEBUG STATUS CONFIRM START !')
        subprocess.call(ADBpath+" wait-for-device",stdout=subprocess.PIPE, shell=subprocess.PIPE)
        print ('ANDROID DEVICE USB DEBUG STATUS CONFIRM END !')
        print ('PRINTSC_CATCH PROCESS SYS_PARAMS. 1、GLOBAL_SCREEN_CATCH：AUTO_CATCH')
        ans.getDeviceInfo()                                                                #设备信息抓取
        print ('PRINTSC_CATCH PROCESS START !')

        while(True):
            try:
                OCR_RECOGNITION_MESSAGE=''                                                 #装载识别出来的文字
                if RUN==True:
                    LOOP_COUNT+=1
                    print ("PRINTSC_CATCH PROCESS CURRENT LOOP CONDITION IS 'TRUE', PROCESS START. LOOP IS ：",LOOP_COUNT," !")
                    ans.getfilePath(filePath)
                    start=time.time()
                    ans.getPrintScreen(filePath,ADBpath)
                    OCR_RECOGNITION_MESSAGE=ans.main(OCR_RECOGNITION_MESSAGE)
                    subprocess.call(ADBpath+' shell rm /sdcard/printScreenImg.jpg',stdout=subprocess.PIPE, shell=subprocess.PIPE)
                    end=time.time()
                    booleanFlag=ans.judgeProcessBreakCondition(OCR_RECOGNITION_MESSAGE,BREAK_CONDITION)
                    if booleanFlag:
                        print ("CURRENT OCR_RECOGNITION_MESSAGE IS :'",OCR_RECOGNITION_MESSAGE,"',MATCH THE BREAK_CONDITION('",BREAK_CONDITION,"') !")
                        ans.sendMessage2Wechat(OCR_RECOGNITION_MESSAGE)
                        print ('PRINTSC_CATCH PROCESS END !')
                        break
                    else:
                        ans.swipeDevice()
                        print ("CURRENT OCR_RECOGNITION_MESSAGE IS :'",OCR_RECOGNITION_MESSAGE,"',NOT MATCH THE BREAK_CONDITION('",BREAK_CONDITION,"') !")
                    print ("PRINTSC_CATCH PROCESS CURRENT LOOP CONDITION IS 'TRUE', PROCESS END. LOOP IS ：",LOOP_COUNT," ! ","TIME COST ：",end-start)
                    print ()
               
                elif EXIT==True:
                    print ('PRINTSC_CATCH PROCESS END !')
                    break
            except Exception as e:
                logger.error('EXCEPTION STACKTRACE:',e)
                break